package com.tlgen.doc.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.text.StringEscapeUtils;
import com.tlgen.doc.model.Doc;
import com.tlgen.doc.model.Param;

import java.util.List;
import java.util.Objects;
import java.util.UUID;

public class ConvertUtils {

    public static String convertApiFox(List<Doc> docs) {
//        System.out.println(JSONObject.toJSONString(docs));
        JSONObject apiFoxObject = new JSONObject();
        apiFoxObject.put("apifoxProject", "1.0.0");
        JSONObject $schemaObject = new JSONObject();
        $schemaObject.put("app", "apifox");
        $schemaObject.put("type", "project");
        $schemaObject.put("version", "1.2.0");
        apiFoxObject.put("$schema", $schemaObject);
        JSONObject infoObject = new JSONObject();
        infoObject.put("name", "生成接口");
        infoObject.put("enableSystemRule", true);
        apiFoxObject.put("info", infoObject);
        JSONArray environmentsArray = new JSONArray();
        JSONObject environmentsObject = new JSONObject();
        environmentsObject.put("name", "本地环境8080");
        environmentsObject.put("type", "normal");
        environmentsObject.put("visibility", "protected");
        environmentsObject.put("ordering", 0);
        JSONArray tagsArray = new JSONArray();
        JSONObject tagsObject = new JSONObject();
        tagsObject.put("name", "");
        tagsObject.put("color", "#9373EE");
        tagsArray.add(tagsObject);
        environmentsObject.put("tags", tagsArray);
        environmentsObject.put("id", UUID.randomUUID());
        environmentsObject.put("baseUrl", "http://localhost:8080");
        JSONObject baseUrlsObject = new JSONObject();
        baseUrlsObject.put("default", "http://localhost:8080");
        environmentsObject.put("baseUrls", baseUrlsObject);
        environmentsArray.add(environmentsObject);
        apiFoxObject.put("environments", environmentsArray);
        JSONObject projectSettingObject = new JSONObject();
        projectSettingObject.put("id", UUID.randomUUID());
        projectSettingObject.put("language", "zh-CN");
        JSONArray serversArray = new JSONArray();
        JSONObject serversObject = new JSONObject();
        serversObject.put("id", "default");
        serversObject.put("name", "默认服务");
        serversArray.add(serversObject);
        projectSettingObject.put("servers", serversArray);
        JSONArray apiStatusesArray = new JSONArray();
        apiStatusesArray.add("developing");
        apiStatusesArray.add("testing");
        apiStatusesArray.add("released");
        apiStatusesArray.add("deprecated");
        projectSettingObject.put("apiStatuses", apiStatusesArray);
        JSONObject cloudMockObject = new JSONObject();
        cloudMockObject.put("security", "free");
        cloudMockObject.put("enable", false);
        cloudMockObject.put("tokenKey", "apifoxToken");
        projectSettingObject.put("cloudMock", cloudMockObject);
        apiFoxObject.put("projectSetting", projectSettingObject);
        JSONArray apiCollectionArray = new JSONArray();
        JSONObject apiCollectionObject = new JSONObject();
        apiCollectionObject.put("name", "根目录");
        JSONArray itemsArray = new JSONArray();
        JSONObject itemObject = new JSONObject();
        itemObject.put("name", "生成文档" + UUID.randomUUID().toString().replaceAll("-", ""));
        itemObject.put("parentId", 0);
        JSONArray urlItemsArray = new JSONArray();
        // 组装多个接口
        for (Doc doc : docs) {
            JSONObject urlItems = new JSONObject();
            urlItems.put("name", doc.getComment());
            JSONObject apiObject = new JSONObject();
            apiObject.put("id", UUID.randomUUID());
            apiObject.put("method", "post");
            apiObject.put("path", doc.getUrl());
            apiObject.put("status", "developing");
            apiObject.put("ordering", 10);
            JSONArray responsesArray = new JSONArray();
            JSONObject responsesObject = new JSONObject();
            responsesObject.put("id", UUID.randomUUID());
            responsesObject.put("name", "成功");
            responsesObject.put("code", 200);
            responsesObject.put("contentType", "json");
            JSONObject jsonSchemaObject = new JSONObject();
            jsonSchemaObject.put("type", "object");
            jsonSchemaObject.put("properties", "{}");
            responsesObject.put("jsonSchema", jsonSchemaObject);
            responsesArray.add(responsesObject);
            apiObject.put("responses", responsesArray);

            JSONArray responseExamplesArray = new JSONArray();
            JSONObject responseExamplesObject = new JSONObject();
            responseExamplesObject.put("name", "成功示例");
            responseExamplesObject.put("data", ""); // \r\n
            responseExamplesObject.put("responseId", UUID.randomUUID());
            responseExamplesObject.put("ordering", 1);
            responseExamplesArray.add(responseExamplesObject);
            apiObject.put("responseExamples", responseExamplesArray);
            JSONObject requestBodyObject = new JSONObject();

            String paramData = doc.getParamData();
            List<Param> paramList = JSONArray.parseArray(paramData, Param.class);
            if (Objects.equals("application/x-www-form-urlencoded", doc.getParamContentType())) {
                requestBodyObject.put("type", "application/x-www-form-urlencoded");
                JSONArray parametersArray = new JSONArray();
                for (Param param : paramList) {
                    JSONObject parametersItemObject = new JSONObject();
                    parametersItemObject.put("required", false);
                    parametersItemObject.put("description", param.getFieldComment());
                    parametersItemObject.put("type", param.getFieldType().toLowerCase());
                    parametersItemObject.put("id", UUID.randomUUID());
                    parametersItemObject.put("example", "");
                    parametersItemObject.put("enable", true);
                    parametersItemObject.put("name", param.getFieldName());
                    parametersArray.add(parametersItemObject);
                }
                requestBodyObject.put("parameters", parametersArray);
                apiObject.put("requestBody", requestBodyObject);
            } else if (Objects.equals("application/json", doc.getParamContentType())) {
                requestBodyObject.put("type", "application/json");
                JSONObject jsonSchemaInRequestBodyObject = new JSONObject();
                jsonSchemaInRequestBodyObject.put("type", "object");
                JSONObject propertiesObject = new JSONObject();
                JSONObject propertiesMockObject = new JSONObject();
                for (Param param : paramList) {
                    JSONObject jsonItemForNameObject = new JSONObject();
                    jsonItemForNameObject.put("type", param.getFieldType().toLowerCase());
                    jsonItemForNameObject.put("title", param.getFieldComment());
                    propertiesObject.put(param.getFieldName(), jsonItemForNameObject);
                    propertiesMockObject.put(param.getFieldName(), "");
                }
                jsonSchemaInRequestBodyObject.put("properties", propertiesObject);
                requestBodyObject.put("jsonSchema", jsonSchemaInRequestBodyObject);
                JSONObject object = JSONObject.parseObject(propertiesMockObject.toJSONString());
                String pretty = JSON.toJSONString(object, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                        SerializerFeature.WriteDateUseDateFormat);
                String s = StringEscapeUtils.escapeJson(pretty);
                requestBodyObject.put("example", s); // \r\n
                apiObject.put("requestBody", requestBodyObject);
            } else if (Objects.equals("query", doc.getParamContentType())) {
                JSONObject parametersObject = new JSONObject();
                JSONArray queryArray = new JSONArray();
                for (Param param : paramList) {
                    JSONObject queryItemObject = new JSONObject();
                    queryItemObject.put("required", false);
                    queryItemObject.put("description", param.getFieldComment());
                    queryItemObject.put("type", param.getFieldType().toLowerCase());
                    queryItemObject.put("id", UUID.randomUUID());
                    queryItemObject.put("enable", true);
                    queryItemObject.put("name", param.getFieldName());
                    queryArray.add(queryItemObject);
                }
                parametersObject.put("query", queryArray);
                apiObject.put("parameters", parametersObject);
            } else if (Objects.equals("pathVariable", doc.getParamContentType())) {
                JSONObject parametersObject = new JSONObject();
                JSONArray pathArray = new JSONArray();
                for (Param param : paramList) {
                    JSONObject pathItemObject = new JSONObject();
                    pathItemObject.put("id", UUID.randomUUID());
                    pathItemObject.put("name", param.getFieldName());
                    pathItemObject.put("required", true);
                    pathItemObject.put("description", param.getFieldComment());
                    pathItemObject.put("type", param.getFieldType().toLowerCase());
                    pathItemObject.put("enable", true);
                    pathArray.add(pathItemObject);
                }
                parametersObject.put("path", pathArray);
                apiObject.put("parameters", parametersObject);
            }
            urlItems.put("api", apiObject);
            urlItemsArray.add(urlItems);
        }
        itemObject.put("items", urlItemsArray);
        itemsArray.add(itemObject);
        apiCollectionObject.put("items", itemsArray);
        apiCollectionArray.add(apiCollectionObject);
        apiFoxObject.put("apiCollection", apiCollectionArray);

        // responseExamples 中的 data 和 requestBody 中的 example 都是保留 \r\n 的
        String jsonString = apiFoxObject.toJSONString();
        String unescapeJava = StringEscapeUtils.unescapeJava(jsonString);
        return unescapeJava;
    }

    public static String removeTranslateStr(String jsonString) {
        jsonString = jsonString.replaceAll("\\\"\\{", "{");
        jsonString = jsonString.replaceAll("\\}\\\"", "}");
        jsonString = jsonString.replaceAll("\\\"\\[", "[");
        jsonString = jsonString.replaceAll("\\]\\\"", "]");
        jsonString = jsonString.replaceAll("\\\\r", "");
        jsonString = jsonString.replaceAll("\\\\n", "");
        jsonString = jsonString.replaceAll("\\\\", "");
        jsonString = jsonString.replaceAll("\\}\\\"", "}");
        String s = StringEscapeUtils.unescapeJava(jsonString);
        return s;
    }

}
